#!/usr/bin/env python3
"""
强制释放数据库连接脚本
用于解决数据库文件被占用的问题
"""

import os
import sys
import gc
import sqlite3
import psutil
from pathlib import Path

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

def force_close_sqlite_connections(db_path):
    """强制关闭SQLite数据库连接"""
    print(f"尝试强制关闭数据库连接: {db_path}")
    
    # 方法1: 尝试通过SQLite直接关闭
    try:
        conn = sqlite3.connect(db_path)
        conn.close()
        print("✓ SQLite连接已关闭")
    except Exception as e:
        print(f"SQLite连接关闭失败: {e}")
    
    # 方法2: 强制垃圾回收
    gc.collect()
    print("✓ 执行垃圾回收")

def find_processes_using_file(file_path):
    """查找正在使用文件的进程"""
    processes = []
    try:
        for proc in psutil.process_iter(['pid', 'name', 'open_files']):
            try:
                if proc.info['open_files']:
                    for file_info in proc.info['open_files']:
                        if file_info.path == file_path:
                            processes.append({
                                'pid': proc.info['pid'],
                                'name': proc.info['name'],
                                'file': file_info.path
                            })
            except (psutil.NoSuchProcess, psutil.AccessDenied):
                continue
    except Exception as e:
        print(f"查找进程时出错: {e}")
    
    return processes

def release_database_connections():
    """释放数据库连接"""
    print("=== 强制释放数据库连接 ===")
    
    try:
        # 导入并释放全局数据库管理器
        from src.models.database.database import dispose_global_db_manager
        dispose_global_db_manager()
        print("✓ 全局数据库管理器已释放")
    except Exception as e:
        print(f"释放全局数据库管理器失败: {e}")
    
    # 获取数据库文件路径
    try:
        from src.core.path_manager import path_manager
        db_path = str(path_manager.get_database_file())
        print(f"数据库文件路径: {db_path}")
        
        if os.path.exists(db_path):
            # 查找使用数据库文件的进程
            processes = find_processes_using_file(db_path)
            if processes:
                print(f"发现 {len(processes)} 个进程正在使用数据库文件:")
                for proc in processes:
                    print(f"  PID: {proc['pid']}, 进程名: {proc['name']}")
            else:
                print("✓ 没有进程正在使用数据库文件")
            
            # 强制关闭连接
            force_close_sqlite_connections(db_path)
            
        else:
            print("数据库文件不存在")
            
    except Exception as e:
        print(f"处理数据库文件时出错: {e}")
    
    print("=== 释放完成 ===")

if __name__ == "__main__":
    release_database_connections() 